package com.mediastory.spsserver.gcm.web;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Message.Builder;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
import com.mediastory.spsserver.gcm.domain.Gcm;
import com.mediastory.spsserver.gcm.service.GcmSvc;

/**
 * @author Jaewon Choi
 */

@Controller
@RequestMapping("/gcm")
public class GcmCtrl {
	
	private final Logger logger = Logger.getLogger(getClass());
	
	@Autowired
	private MessageSourceAccessor messages;
	
	@Autowired
	private GcmSvc gcmSvc;

	
	/**
	 * 목록 보기
	 * */
	@RequestMapping(value={"/list.do"})
	public Map<String, Object> list(HttpServletRequest request) throws Exception {
		Map<String, Object> condition = new HashMap<String, Object>();
		//검색 parameter
		String beginTime = ServletRequestUtils.getStringParameter(request, "beginTime");
		String endTime = ServletRequestUtils.getStringParameter(request, "endTime");
		
		condition.put("beginTime", beginTime);
		condition.put("endTime", endTime);
		
		//페이징 처리 parameter
		int maxnum = ServletRequestUtils.getIntParameter(request, "maxnum", 10);
		int page = ServletRequestUtils.getIntParameter(request, "page", 1);
		condition.put("maxnum", maxnum);
		condition.put("page", (page-1)*maxnum);
		
		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.putAll(gcmSvc.findbyListPaging(condition));
		resultMap.put("maxnum", maxnum);
		resultMap.put("page", page);
		
		return resultMap;
	}
	
	/**
	 * 상세보기
	 * */
	@RequestMapping(value={"/detail.do"})
	public Map<String, Object> detail(HttpServletRequest request, HttpSession session, @RequestParam(required=true, value="idx")  Integer idx) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		
		//gcm
		resultMap.put("gcm", gcmSvc.findby(idx));
		
		//gcm data list
		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("gcmIdx", idx);
		resultMap.put("gcmDataList", gcmSvc.findbyListData(condition));
		
		return resultMap;
	}

	/**
	 * 등록,수정 폼
	 * */
	@RequestMapping(value={"/form.do"})
	public Map<String, Object> form(HttpServletRequest request) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();

		int idx = ServletRequestUtils.getIntParameter(request, "idx", 0);
		if(idx != 0){
			//gcm
			resultMap.put("gcm", gcmSvc.findby(idx));
			
			//gcm data list
			Map<String, Object> condition = new HashMap<String, Object>();
			condition.put("gcmIdx", idx);
			resultMap.put("gcmDataList", gcmSvc.findbyListData(condition));
		}
		
		return resultMap;
	}
	
	/**
	 * 등록/수정
	 * */
	@RequestMapping(value={"/submit.do"}, method=RequestMethod.POST)
	public String submit(Gcm gcm, HttpServletRequest request, HttpSession session) throws Exception {
		String userId = (String)session.getAttribute("userId");
		String ip = request.getRemoteAddr();
		
		if(gcm.getIdx() != null){
			gcm.setModifiedId(userId);
			gcm.setModifiedIp(ip);
			gcmSvc.modify(gcm);
		}else{
			gcm.setCreatedId(userId);
			gcm.setCreatedIp(ip);
			gcmSvc.add(gcm);
		}

		return "gcm/result";
	}
	
	/**
	 * 삭제
	 * */
	@RequestMapping(value={"/remove.do"}, method=RequestMethod.POST)
	public String remove(HttpServletRequest request, HttpSession session) throws Exception {
		
		String userId = (String)session.getAttribute("userId");
		String ip = request.getRemoteAddr();
		
		int[] idx = ServletRequestUtils.getIntParameters(request, "idx");
		
		if(idx.length == 0){
			throw new Exception("[ERROR] 삭제할 [메시지]를 하나 이상 선택하셔야 합니다.");
		}
		
		Map<String, Object> condition = new HashMap<String, Object>();
		condition.put("modifiedId", userId);
		condition.put("modifiedIp", ip);
		condition.put("idx", idx);
		
		gcmSvc.remove(condition);
		return "gcm/result";
	}

	/**
	 * GCM 발송
	 * */
	@RequestMapping(value={"/send.do"})
	public ModelAndView send(HttpServletRequest request, HttpSession session) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		
		String userId = (String)session.getAttribute("userId");
		String ip = request.getRemoteAddr();
		
		Gcm gcmObj = new Gcm();
		gcmObj.setModifiedId(userId);
		gcmObj.setModifiedIp(ip);
		List<Gcm> result = gcmSvc.sendMsg(gcmObj, false);

		/*
		mApiKey : api console 의 api 키 값
		message : 보낼 message 이며, Message.Builer() 에서 addData를 통해서 key velue 를 넣을수 있다.
		devices : push reg id 의 list
		
		String myApiKey = "AIzaSyATtXCiobzZh7mV8LWy7A3NniC0Aqv00Cw";
		
		Map<String, Object> condition = new HashMap<String, Object>();
		
		//gcm 목록
		condition.put("status", 1);//발송 대기 상태
		List<Gcm> gcmList = gcmSvc.findbyList(condition);
		
		//gcm device 목록
		List<String> devices = (List<String>)gcmSvc.findbyListDevice(condition);
		
		Sender sender = new Sender(myApiKey);
		Builder builder = new Message.Builder();

		//gcm data
		for(Gcm gcm : gcmList){
			int idx = gcm.getIdx();
			String title = gcm.getTitle();
			
			condition.put("gcmIdx", idx);
			List<Map<String, Object>> gcmDataList = gcmSvc.findbyListData(condition);
			builder.addData("title", URLEncoder.encode(title, "UTF-8"));
			for(Map<String, Object> gcmData : gcmDataList){
				String dataKey = URLEncoder.encode((String)gcmData.get("key"), "UTF-8");
				String data = URLEncoder.encode((String)gcmData.get("data"), "UTF-8");
				builder.addData(dataKey, data);
			}

			Message message = builder.build();
			MulticastResult result = sender.send(message, devices, 5);
			long successCnt = result.getSuccess();
			System.out.println(successCnt);
			long failureCnt = result.getFailure();
			System.out.println(failureCnt);
			
			//성공, 실패 개수, 상태(발송 완료) 수정
			gcm.setSuccessCnt(successCnt);
			gcm.setFailureCnt(failureCnt);
			gcm.setStatus(2);
		}
		*/
		
/*
		if (result.getMessageId() != null) {
			String canonicalRegId = result.getCanonicalRegistrationId();
			if (canonicalRegId != null) {
				//same device has more than on registration ID: update database
			}
		} else {
			String error = result.getErrorCodeName();
			if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
				//application has been removed from device - unregister database
			}
		}
*/
		return new ModelAndView("redirect:/gcm/list.do");
	}
	
	/**
	 * GCM 발송 테스트
	 * */
	@RequestMapping(value={"/sendTest.do"})
	public Map<String, Object> sendTest(HttpServletRequest request, HttpSession session) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		
		/*
		mApiKey : api console 의 api 키 값
		message : 보낼 message 이며, Message.Builer() 에서 addData를 통해서 key velue 를 넣을수 있다.
		devices : push reg id 의 list
		*/
		
		String title = ServletRequestUtils.getStringParameter(request, "title", "");
		String subtitle = ServletRequestUtils.getStringParameter(request, "subtitle", "");
		String msg = ServletRequestUtils.getStringParameter(request, "message", "");
		String deviceKey = ServletRequestUtils.getStringParameter(request, "deviceKey", "");
		
		if(deviceKey != null && ! deviceKey.equals("")){
			String myApiKey = messages.getMessage("gcm.api.key");
			
			Sender sender = new Sender(myApiKey);
			Builder builder = new Message.Builder();
			builder.addData("title", URLEncoder.encode(title, "UTF-8"));
			builder.addData("subtitle", URLEncoder.encode(subtitle, "UTF-8"));
			builder.addData("message", URLEncoder.encode(msg, "UTF-8"));
			
			Message message = builder.build();
			Result result = sender.send(message, deviceKey, 5);
			resultMap.put("errorCodeName", result.getErrorCodeName());
		}

		return resultMap; 
/*
		if (result.getMessageId() != null) {
			String canonicalRegId = result.getCanonicalRegistrationId();
			if (canonicalRegId != null) {
				//same device has more than on registration ID: update database
			}
		} else {
			String error = result.getErrorCodeName();
			if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
				//application has been removed from device - unregister database
			}
		}
*/
	}

}